// Copyright 2000-2020 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file.
package com.intellij.java.psi;

import com.intellij.psi.CommonClassNames;
import com.intellij.psi.PsiNameHelper;
import org.junit.Assert;
import org.junit.Test;

public class PsiNameHelperTest {
  @Test
  public void shortClassName() {
    doTest("I<Integer>", "I");
    doTest("I<Long>", "I");
    doTest("java.lang.Object", "Object");
    doTest("java.lang.String", "String");
    doTest(CommonClassNames.JAVA_LANG_THROWABLE, "Throwable");
    doTest("java.io.PrintStream", "PrintStream");
    doTest("java.io.PrintWriter", "PrintWriter");
    doTest("java.lang.StackTraceElement", "StackTraceElement");
    doTest("java.lang.Throwable.PrintStreamOrWriter", "PrintStreamOrWriter");
    doTest("java.io.ObjectInputStream", "ObjectInputStream");
    doTest("java.io.ObjectOutputStream", "ObjectOutputStream");
    doTest("java.lang.Integer", "Integer");
    doTest("java.lang.Long", "Long");
    doTest("java.lang.Error", "Error");
    doTest("java.lang.RuntimeException", "RuntimeException");
    doTest("@Override", "Override");
    doTest("java.lang.annotation.Target", "Target");
    doTest("java.net.MalformedURLException", "MalformedURLException");
    doTest("java.io.IOException", "IOException");
    doTest("java.net.URLConnection", "URLConnection");
    doTest("java.io.InputStream", "InputStream");
    doTest("java.lang.AutoCloseable", "AutoCloseable");
    doTest("@", "");
    doTest("@Deprecated", "Deprecated");
    doTest("java.lang.annotation.Documented", "Documented");
    doTest("java.lang.annotation.Retention", "Retention");
    doTest("CSuperFoo<X>", "CSuperFoo");
    doTest("SuperFoo<X>", "SuperFoo");
    doTest("java.lang.StringBuffer", "StringBuffer");
    doTest("java.lang.StringBuilder", "StringBuilder");
    doTest("Member<>", "Member");
    doTest("Nested<>", "Nested");
    doTest("Neg09.Nested<>", "Nested");
    doTest("UndeclaredName<>", "UndeclaredName");
    doTest("L<String>", "L");
    doTest("P1<P<K>>", "P1");
    doTest("P<P1T>", "P");
    doTest("F<X>", "F");
    doTest("Base<String>", "Base");
    doTest("Base<Integer>", "Base");
    doTest("A<V>", "A");
    doTest("ArrayList<T>", "ArrayList");
    doTest("I<>", "I");
    doTest("java.util.Collection<? extends E>", "Collection");
    doTest("java.util.Map<? extends K,? extends V>", "Map");
    doTest("java.util.HashMap.Entry", "Entry");
    doTest("java.util.Iterator<E>", "Iterator");
    doTest("java.util.ListIterator<E>", "ListIterator");
    doTest("java.util.List<E>", "List");
    doTest("@SuppressWarnings", "SuppressWarnings");
    doTest("java.lang.annotation.Annotation", "Annotation");
    doTest("@MyAnno", "MyAnno");
    doTest("java.lang.Exception", "Exception");
    doTest("@SafeVarargs", "SafeVarargs");
    doTest("List<T>", "List");
    doTest("List<String>", "List");
    doTest("List<?>", "List");
    doTest("SemKey<String>", "SemKey");
    doTest("Condition<String>", "Condition");
    doTest("SemKey<T>", "SemKey");
    doTest("java.lang.Class<?>", "Class");
    doTest("A<T>", "A");
    doTest("java.lang.invoke.MethodType", "MethodType");
    doTest("java.lang.CharSequence", "CharSequence");
    doTest("java.lang.IllegalAccessException", "IllegalAccessException");
    doTest("java.util.Locale", "Locale");
    doTest("java.util.List<java.lang.Class<?>>", "List");
    doTest("java.lang.Void", "Void");
    doTest("java.lang.invoke.MethodHandles.Lookup", "Lookup");
    doTest("java.lang.invoke.MethodHandle", "MethodHandle");
    doTest("java.lang.invoke.MethodHandle.PolymorphicSignature", "PolymorphicSignature");
    doTest("Map<String, String>", "Map");
    doTest("List<N>", "List");
    doTest("Wrapper<E, T>", "Wrapper");
    doTest("X<T>", "X");
    doTest("Node<String>.Details", "Details");
    doTest("Map<K, V>", "Map");
    doTest("Map.Entry<K, V>", "Entry");
    doTest("Matcher<Collection<? extends E>>", "Matcher");
    doTest("A<String>", "A");
    doTest("NonDefaultConstructorContainer.Inner", "Inner");
    doTest("OtherClass.InnerClass", "InnerClass");
    doTest("Foo<Number>", "Foo");
    doTest("Foo<Integer>", "Foo");
    doTest("Test<String>", "Test");
    doTest("DiamondTest<String>", "DiamondTest");
    doTest("ParallelPipeline<T, V>", "ParallelPipeline");
    doTest("ArrayList<E>", "ArrayList");
    doTest("Generic<String>", "Generic");
    doTest("Generic<Object>", "Generic");
    doTest("java.io.Serializable", "Serializable");
    doTest("java.lang.Comparable<java.lang.String>", "Comparable");
    doTest("@Target", "Target");
    doTest("@TA", "TA");
    doTest("java.lang.Enum", "Enum");
    doTest("java.io.OutputStream", "OutputStream");
    doTest("java.io.OutputStreamWriter", "OutputStreamWriter");
    doTest("java.io.File", "File");
    doTest("Foo.IBar", "IBar");
    doTest("Iterable<Path>", "Iterable");
    doTest("B<Integer>", "B");
    doTest("B<Long>", "B");
    doTest("java.lang.AbstractStringBuilder", "AbstractStringBuilder");
    doTest("@NotNull", "NotNull");
    doTest("@Nullable", "Nullable");
    doTest("java.lang.Runnable", "Runnable");
    doTest("java.io.FileDescriptor", "FileDescriptor");
    doTest("java.io.FileNotFoundException", "FileNotFoundException");
    doTest("java.sql.SQLException", "SQLException");
    doTest("java.awt.Point", "Point");
    doTest("List<A.B>", "List");
    doTest("test.A", "A");
    doTest("test.Client", "Client");
    doTest("Pair<String, Pair<Integer, Boolean>>", "Pair");
    doTest("util.Pair", "Pair");
    doTest("java.util.Calendar", "Calendar");
    doTest("java.util.ArrayList", "ArrayList");
    doTest("java.util.Arrays", "Arrays");
    doTest("java.util.List", "List");
    doTest("java.lang.Boolean", "Boolean");
    doTest("java.lang.ClassLoader", "ClassLoader");
    doTest("Demo.Pojo2", "Pojo2");
    doTest("A<E>", "A");
    doTest("java.lang.reflect.Type", "Type");
    doTest("java.security.ProtectionDomain", "ProtectionDomain");
    doTest("java.lang.reflect.Field", "Field");
    doTest("java.lang.reflect.Method", "Method");
    doTest("java.lang.reflect.Constructor", "Constructor");
    doTest("sun.reflect.annotation.AnnotationType", "AnnotationType");
    doTest("java.lang.reflect.TypeVariable<java.lang.Class<T>>", "TypeVariable");
    doTest("java.lang.reflect.TypeVariable<?>", "TypeVariable");
    doTest("java.lang.Class<T>", "Class");
    doTest("Parent<Integer>", "Parent");
    doTest("@org.jetbrains.annotations.NotNull", "NotNull");
    doTest("@org.jetbrains.annotations.Nullable", "Nullable");
    doTest("org.jetbrains.annotations.NotNull", "NotNull");
    doTest("org.jetbrains.annotations.Nullable", "Nullable");
    doTest("IX<Throwable>", "IX");
    doTest("@org.testng.annotations.BeforeMethod", "BeforeMethod");
    doTest("Function<String, ?>", "Function");
    doTest("Function<String>", "Function");
    doTest("A<Throwable>", "A");
    doTest("Generic<?>", "Generic");
    doTest("A1<T>", "A1");
    doTest("B<T>", "B");
    doTest("pack.AAClass", "AAClass");
    doTest("pack.WithInnerAClass", "WithInnerAClass");
    doTest("java.lang.CloneNotSupportedException", "CloneNotSupportedException");
    doTest("Foo<ZZZ", "Foo");
    doTest("@MyObj", "MyObj");
    doTest("@MyObjectType", "MyObjectType");
    doTest("@Retention", "Retention");
    doTest("java.io.FileInputStream", "FileInputStream");
    doTest("java.lang.Class<? extends java.lang.Object>", "Class");
    doTest("java.io.ObjectStreamField", "ObjectStreamField");
    doTest("java.util.Comparator<java.lang.String>", "Comparator");
    doTest("java.io.FilenameFilter", "FilenameFilter");
    doTest("java.lang.Class", "Class");
    doTest("foo.Foo", "Foo");
    doTest("java.util.List<? super T>", "List");
    doTest("java.awt.Component", "Component");
    doTest("java.util.Collection<?>", "Collection");
    doTest("java.awt.Rectangle", "Rectangle");
    doTest("javax.swing.JTable", "JTable");
    doTest("javax.swing.JScrollPane", "JScrollPane");
    doTest("java.awt.Container", "Container");
    doTest("java.net.FileNameMap", "FileNameMap");
    doTest("java.awt.Frame", "Frame");
    doTest("java.util.List<?>", "List");
    doTest("java.awt.event.MouseEvent", "MouseEvent");
    doTest("javax.swing.Action", "Action");
    doTest("javax.swing.KeyStroke", "KeyStroke");
    doTest("java.awt.event.KeyEvent", "KeyEvent");
    doTest("java.io.DataInput", "DataInput");
    doTest("java.net.ContentHandlerFactory", "ContentHandlerFactory");
    doTest("java.net.DatagramSocketImplFactory", "DatagramSocketImplFactory");
    doTest("java.net.SocketImplFactory", "SocketImplFactory");
    doTest("java.net.URLStreamHandlerFactory", "URLStreamHandlerFactory");
    doTest("java.util.Collection<? extends T>", "Collection");
    doTest("java.util.Collection<T>", "Collection");
    doTest("java.util.List<? extends T>", "List");
    doTest("java.util.List<T>", "List");
    doTest("java.util.Map<K,V>", "Map");
    doTest("java.util.Set<? extends T>", "Set");
    doTest("java.util.Set<T>", "Set");
    doTest("java.util.SortedMap<K,? extends V>", "SortedMap");
    doTest("java.util.SortedMap<K,V>", "SortedMap");
    doTest("java.util.SortedSet<T>", "SortedSet");
    doTest("java.lang.Float", "Float");
    doTest("java.lang.Double", "Double");
    doTest("java.lang.Short", "Short");
    doTest("java.lang.annotation.ElementType", "ElementType");
    doTest("java.lang.Byte", "Byte");
    doTest("java.util.concurrent.TimeUnit", "TimeUnit");
    doTest("java.lang.annotation.RetentionPolicy", "RetentionPolicy");
    doTest("java.lang.Character", "Character");
    doTest("java.sql.Time", "Time");
    doTest("java.sql.Date", "Date");
    doTest("java.sql.Timestamp", "Timestamp");
    doTest("java.awt.Window", "Window");
    doTest("Some<caret>", "Some");
    doTest("foo.bar.AxBxCxDxEx", "AxBxCxDxEx");
    doTest("net.n3.nanoxml.IXMLReader", "IXMLReader");
    doTest("net.n3.nanoxml.IXMLBuilder", "IXMLBuilder");
    doTest("net.n3.nanoxml.IXMLValidator", "IXMLValidator");
    doTest("net.n3.nanoxml.IXMLEntityResolver", "IXMLEntityResolver");
    doTest("java.util.Vector", "Vector");
    doTest("foo.MyClass", "MyClass");
    doTest("foo.ServiceManager", "ServiceManager");
    doTest("Bar<String>", "Bar");
    doTest("pkg.Bar", "Bar");
    doTest("java.util.Random", "Random");
    doTest("java.util.Set", "Set");
    doTest("java.util.Map", "Map");
    doTest("java.util.Comparator", "Comparator");
    doTest("java.util.Collection<E>", "Collection");
    doTest("java.util.Set<E>", "Set");
    doTest("java.util.SortedSet<E>", "SortedSet");
    doTest("java.util.Comparator<T>", "Comparator");
    doTest("java.util.Enumeration<T>", "Enumeration");
    doTest("pkg.Foo", "Foo");
    doTest("foo.Bar", "Bar");
    doTest("sun.nio.ch.Interruptible", "Interruptible");
    doTest("java.lang.ThreadGroup", "ThreadGroup");
    doTest("java.lang.Thread", "Thread");
    doTest("java.lang.Iterable", "Iterable");
    doTest("java.lang.Package", "Package");
    doTest("java.lang.reflect.Constructor<?>", "Constructor");
    doTest("java.lang.reflect.Constructor<T>", "Constructor");
    doTest("java.lang.Class<U>", "Class");
    doTest("java.lang.Class<A>", "Class");
    doTest("java.lang.Class<? extends java.lang.annotation.Annotation>", "Class");
    doTest("foo.Util", "Util");
    doTest("java.lang.SecurityManager", "SecurityManager");
    doTest("java.util.Properties", "Properties");
    doTest("java.util.Map<java.lang.String,java.lang.String>", "Map");
    doTest("java.lang.Class<W>", "Class");
    doTest("java.lang.Class<V>", "Class");
    doTest("@Foo", "Foo");
    doTest("@Anno", "Anno");
    doTest("java.awt.Font", "Font");
    doTest("java.awt.Graphics", "Graphics");
    doTest("java.awt.Color", "Color");
    doTest("java.awt.Dimension", "Dimension");
    doTest("java.awt.Event", "Event");
    doTest("java.awt.PopupMenu", "PopupMenu");
    doTest("java.awt.MenuComponent", "MenuComponent");
    doTest("java.beans.PropertyChangeListener", "PropertyChangeListener");
    doTest("java.awt.ComponentOrientation", "ComponentOrientation");
    doTest("java.awt.LayoutManager", "LayoutManager");
    doTest("javax.swing.JPopupMenu", "JPopupMenu");
    doTest("javax.swing.border.Border", "Border");
    doTest("java.awt.Insets", "Insets");
    doTest("javax.swing.InputVerifier", "InputVerifier");
    doTest("java.awt.event.ActionListener", "ActionListener");
    doTest("javax.swing.ComponentInputMap", "ComponentInputMap");
    doTest("javax.swing.ActionMap", "ActionMap");
    doTest("javax.swing.TransferHandler", "TransferHandler");
    doTest("javax.swing.event.AncestorListener", "AncestorListener");
    doTest("javax.swing.JComponent", "JComponent");
    doTest("java.awt.event.ContainerListener", "ContainerListener");
    doTest("java.awt.AWTEvent", "AWTEvent");
    doTest("java.awt.event.ContainerEvent", "ContainerEvent");
    doTest("java.awt.FocusTraversalPolicy", "FocusTraversalPolicy");
    doTest("java.awt.dnd.DropTarget", "DropTarget");
    doTest("java.awt.PointerInfo", "PointerInfo");
    doTest("java.awt.Cursor", "Cursor");
    doTest("java.awt.Image", "Image");
    doTest("java.awt.image.ImageProducer", "ImageProducer");
    doTest("java.awt.event.MouseWheelEvent", "MouseWheelEvent");
    doTest("java.awt.event.ComponentListener", "ComponentListener");
    doTest("java.awt.event.FocusListener", "FocusListener");
    doTest("java.awt.event.HierarchyListener", "HierarchyListener");
    doTest("java.awt.event.HierarchyBoundsListener", "HierarchyBoundsListener");
    doTest("java.awt.event.KeyListener", "KeyListener");
    doTest("java.awt.event.MouseListener", "MouseListener");
    doTest("java.awt.event.MouseMotionListener", "MouseMotionListener");
    doTest("java.awt.event.MouseWheelListener", "MouseWheelListener");
    doTest("java.awt.event.InputMethodListener", "InputMethodListener");
    doTest("java.awt.event.ComponentEvent", "ComponentEvent");
    doTest("java.awt.event.FocusEvent", "FocusEvent");
    doTest("java.awt.event.InputMethodEvent", "InputMethodEvent");
    doTest("java.awt.event.HierarchyEvent", "HierarchyEvent");
    doTest("java.util.EventListener", "EventListener");
    doTest("javax.accessibility.AccessibleContext", "AccessibleContext");
    doTest("java.awt.peer.ContainerPeer", "ContainerPeer");
    doTest("javax.swing.InputMap", "InputMap");
    doTest("javax.swing.JToolTip", "JToolTip");
    doTest("javax.swing.JRootPane", "JRootPane");
    doTest("java.awt.peer.ComponentPeer", "ComponentPeer");
    doTest("java.awt.GraphicsConfiguration", "GraphicsConfiguration");
    doTest("java.awt.Toolkit", "Toolkit");
    doTest("java.awt.image.ColorModel", "ColorModel");
    doTest("java.awt.FontMetrics", "FontMetrics");
    doTest("java.awt.image.VolatileImage", "VolatileImage");
    doTest("java.awt.ImageCapabilities", "ImageCapabilities");
    doTest("java.awt.image.ImageObserver", "ImageObserver");
    doTest("java.awt.im.InputMethodRequests", "InputMethodRequests");
    doTest("java.awt.im.InputContext", "InputContext");
    doTest("javax.swing.JPanel", "JPanel");
    doTest("@T", "T");
    doTest("java.util.Set<K>", "Set");
    doTest("java.util.Collection<V>", "Collection");
    doTest("java.util.Set<java.util.Map.Entry<K,V>>", "Set");
    doTest("java.util.Map.Entry<K,V>", "Entry");
    doTest("java.util.TimeZone", "TimeZone");
    doTest("java.util.Date", "Date");
    doTest("AbstractSet<T>", "AbstractSet");
    doTest("@TestFor", "TestFor");
    doTest("@MyAnnotation", "MyAnnotation");
    doTest("@My", "My");
    doTest("@Test", "Test");
    doTest("List<V>", "List");
    doTest("Function<Object, ArrayIndexOutOfBoundsException>", "Function");
    doTest("@in", "in");
    doTest("YourMapInterface<K, V>", "YourMapInterface");
    doTest("@ab", "ab");
    doTest("List<A>", "List");
    doTest("@MyAn", "MyAn");
    doTest("@java.la", "la");
    doTest("java.lang.Class<E>", "Class");
    doTest("javax.accessibility.AccessibleStateSet", "AccessibleStateSet");
    doTest("Bar.", "");
    doTest("@TestAnnotation", "TestAnnotation");
    doTest("Key<T>", "Key");
    doTest("foo.Super", "Super");
    doTest("@NN", "NN");
    doTest("java.io.InputStreamReader", "InputStreamReader");
    doTest("foo.StringValue", "StringValue");
    doTest("@B", "B");
    doTest("@Example", "Example");
    doTest("java.util.HashMap", "HashMap");
    doTest("@MagicConstant", "MagicConstant");
    doTest("List<Inner>", "List");
    doTest("List<bar.Foo.Inner>", "List");
    doTest("bar.Foo", "Foo");
    doTest("bar.Assert", "Assert");
    doTest("java.util.Collections", "Collections");
    doTest("Foo<String>", "Foo");
    doTest("Bar<Goo>", "Bar");
    doTest("java.util.Collection", "Collection");
    doTest("Collection<Foo>", "Collection");
    doTest("java.net.URL", "URL");
    doTest("java.util.Enumeration", "Enumeration");
    doTest("java.lang.ref.SoftReference", "SoftReference");
    doTest("sun.reflect.generics.repository.ClassRepository", "ClassRepository");
    doTest("sun.reflect.ReflectionFactory", "ReflectionFactory");
    doTest("java.lang.Class.EnclosingMethodInfo", "EnclosingMethodInfo");
    doTest("sun.reflect.generics.factory.GenericsFactory", "GenericsFactory");
    doTest("sun.reflect.ConstantPool", "ConstantPool");
    doTest("javax.swing.event.EventListenerList", "EventListenerList");
    doTest("javax.swing.ArrayTable", "ArrayTable");
    doTest("javax.swing.AncestorNotifier", "AncestorNotifier");
    doTest("java.awt.LightweightDispatcher", "LightweightDispatcher");
    doTest("sun.awt.DebugHelper", "DebugHelper");
    doTest("javax.accessibility.Accessible", "Accessible");
    doTest("java.util.logging.Logger", "Logger");
    doTest("sun.awt.AppContext", "AppContext");
    doTest("java.awt.image.BufferStrategy", "BufferStrategy");
    doTest("java.beans.PropertyChangeSupport", "PropertyChangeSupport");
    doTest("java.awt.Component.NativeInLightFixer", "NativeInLightFixer");
    doTest("java.util.concurrent.ConcurrentHashMap<java.lang.String,java.util.Locale>", "ConcurrentHashMap");
    doTest("sun.util.resources.OpenListResourceBundle", "OpenListResourceBundle");
    doTest("java.text.MessageFormat", "MessageFormat");
    doTest("java.security.Provider", "Provider");
    doTest("Super<String>", "Super");
    doTest("Super<Integer>", "Super");
    doTest("Super<T>", "Super");
    doTest("SubGeneric<T>", "SubGeneric");
    doTest("MyDD<String>", "MyDD");
    doTest("java.lang.Class<java.lang.Boolean>", "Class");
    doTest("MyProcessor<T>", "MyProcessor");
    doTest("Pair<A,B>", "Pair");
    doTest("foo.Foo<T>", "Foo");
    doTest("java.net.URI", "URI");
    doTest("FList<T>", "FList");
    doTest("java.util.ArrayList<T>", "ArrayList");
    doTest("XXX<X>", "XXX");
    doTest("XXX<Z>", "XXX");
    doTest("XXX<Z, Z1>", "XXX");
    doTest("XXX<ZZZ<Z>>", "XXX");
    doTest("Set<T>", "Set");
    doTest("Outer.Boo", "Boo");
    doTest("Params<", "Params");
    doTest("Key<Impl>", "Key");
    doTest("ExtensionPointName<T>", "ExtensionPointName");
    doTest("X<String>", "X");
    doTest("A<StringBuffer>", "A");
    doTest("Function<String, String>", "Function");
    doTest("java.io.FileFilter", "FileFilter");
    doTest("@Join", "Join");
    doTest("@Table", "Table");
    doTest("Computable<Boolean>", "Computable");
    doTest("Comparable<Foo>", "Comparable");
    doTest("Goo<String>", "Goo");
    doTest("Comparator<String>", "Comparator");
    doTest("@A", "A");
    doTest("java.awt.geom.Point2D.Double", "Double");
    doTest("java.awt.geom.Point2D", "Point2D");
    doTest("bar.Bar", "Bar");
    doTest("A<T[]>", "A");
    doTest("IA<String>", "IA");
    doTest("B<K>", "B");
    doTest("ArgumentA<Object>", "ArgumentA");
    doTest("ClassB<E>", "ClassB");
    doTest("ClassA<E>", "ClassA");
    doTest("BaseMatcher<String>", "BaseMatcher");
    doTest("x.A", "A");
    doTest("x.sub.B", "B");
    doTest("effectiveAccess.pp<", "pp");
    doTest("effectiveAccess.pp", "pp");
    doTest("BaseImpl.Inner", "Inner");
    doTest("x.Base", "Base");
    doTest("@java.lang.Deprecated", "Deprecated");
    doTest("I<II>", "I");
    doTest("C<Q>", "C");
    doTest("AC<CC>", "AC");
    doTest("@Deprecated Object", "Object");
    doTest("@Ann", "Ann");
    doTest("@In", "In");
    doTest("@Inner2", "Inner2");
    doTest("@java.lang", "lang");
    doTest("@Expose", "Expose");
    doTest("@Expose1", "Expose1");
    doTest("DummyList<? extends String>", "DummyList");
    doTest("C<C<U>>", "C");
    doTest("C1<C1<U>>", "C1");
    doTest("CC<T>", "CC");
    doTest("Gen<GT>", "Gen");
    doTest("A1<String>", "A1");
    doTest("I1<Integer>", "I1");
    doTest("II1<Integer>", "II1");
    doTest("II2<Integer>", "II2");
    doTest("II2<String>", "II2");
    doTest("II1<Number>", "II1");
    doTest("II2<Number>", "II2");
    doTest("AAA<T>", "AAA");
    doTest("III<T>", "III");
    doTest("Cmp<Singleton<T1>>", "Cmp");
    doTest("e<String>", "e");
    doTest("ValueChangeListener<Number>", "ValueChangeListener");
    doTest("First<S>", "First");
    doTest("Second<Integer>", "Second");
    doTest("SuperA<T, E>", "SuperA");
    doTest("SuperB<T, E>", "SuperB");
    doTest("Super<Collection>", "Super");
    doTest("TypeDispatcher<T,V>", "TypeDispatcher");
    doTest("DefaultDispatcher<Node, String>", "DefaultDispatcher");
    doTest("SmartList<Bug2>", "SmartList");
    doTest("java.util.List<Bug2>", "List");
    doTest("java.util.AbstractList<E>", "AbstractList");
    doTest("TableContextAction<Object>", "TableContextAction");
    doTest("ActionContext<TableContextAction<TCP>>", "ActionContext");
    doTest("ContextAction<TableContext<RO>>", "ContextAction");
    doTest("Listener<String>", "Listener");
    doTest("I<I>", "I");
    doTest("I<T>", "I");
    doTest("I<D>", "I");
    doTest("DT<T>", "DT");
    doTest("b<d, c>", "b");
    doTest("c<d, c<c,c>>", "c");
    doTest("d<b<c<c,c>,d>>", "d");
    doTest("c<K, c<V,V>>", "c");
    doTest("d<b<V,K>>", "d");
    doTest("Z<Integer>", "Z");
    doTest("BaseC<String>", "BaseC");
    doTest("Int<T>", "Int");
    doTest("A<A>", "A");
    doTest("Outer<String>", "Outer");
    doTest("Outer<String>.Inner", "Inner");
    doTest("AbstractClass<AI>", "AbstractClass");
    doTest("AbstractClass<BI>", "AbstractClass");
    doTest("PrivilegedExceptionAction<FileNotFoundException>", "PrivilegedExceptionAction");
    doTest("Printer<T>", "Printer");
    doTest("I1<C1,C2>", "I1");
    doTest("I2<C1,C2>", "I2");
    doTest("List<Decl>", "List");
    doTest("Reference<T>", "Reference");
    doTest("Comparable<? super ccc>", "Comparable");
    doTest("ArrayList<G1>", "ArrayList");
    doTest("WeakReference<T>", "WeakReference");
    doTest("Y<Y>", "Y");
    doTest("ArrayList<String>", "ArrayList");
    doTest("Comparable<C>", "Comparable");
    doTest("Comparable<String>", "Comparable");
    doTest("ZZZ<K>", "ZZZ");
    doTest("Callable<T>", "Callable");
    doTest("GenericTest99<E,Double>", "GenericTest99");
    doTest("Use99<GenericTest99D<?>,Double>", "Use99");
    doTest("A67675<T[]>", "A67675");
    doTest("java.util.Comparator<? super T>", "Comparator");
    doTest("I2<", "I2");
    doTest("java.util.Map<K, V>", "Map");
    doTest("AA<BB>", "AA");
    doTest("GrandParent<T>", "GrandParent");
    doTest("Base<T[]>", "Base");
    doTest("Base<T>", "Base");
    doTest("AbstractParent<E>", "AbstractParent");
    doTest("Interface<E>", "Interface");
    doTest("SuperAbstract<Owner, String>", "SuperAbstract");
    doTest("HalfGenericSuper<Owner>", "HalfGenericSuper");
    doTest("List<E>", "List");
    doTest("Comparable<A<T>>", "Comparable");
    doTest("A<", "A");
    doTest("Runnable<", "Runnable");
    doTest("HashMap<K, V>", "HashMap");
    doTest("Comparable<Object>", "Comparable");
    doTest("A<K>", "A");
    doTest("Base <String>", "Base");
    doTest("Outer<Other>", "Outer");
    doTest("Lst<?, ?>", "Lst");
    doTest("Collection<A>", "Collection");
    doTest("Matcher<? super T>", "Matcher");
    doTest("ThingUser<?>", "ThingUser");
    doTest("YO<String>", "YO");
    doTest("YO<Integer>", "YO");
    doTest("ArrayList<Integer>", "ArrayList");
    doTest("Comparable<Date>", "Comparable");
    doTest("List<Class<? extends Serializable>>", "List");
    doTest("java.lang.Cloneable", "Cloneable");
    doTest("Test1<ArrayList>", "Test1");
    doTest("Comparator<Object>", "Comparator");
    doTest("TestIF3<T>", "TestIF3");
    doTest("TestBase<Enum1>", "TestBase");
    doTest("Comparable<SortTest<R>>", "Comparable");
    doTest("TypeSafeMap<CoreMap>", "TypeSafeMap");
    doTest("TypeSafeMap.Key<CoreMap, V>", "Key");
    doTest("Map<K,V>", "Map");
    doTest("Version<V, R>", "Version");
    doTest("Ref<V, R>", "Ref");
    doTest("VersionEntity<G, GR>", "VersionEntity");
    doTest("RefEntity<G, GR>", "RefEntity");
    doTest("Node<?, ?>", "Node");
    doTest("IQ<", "IQ");
    doTest("P<TB>", "P");
    doTest("DomInvocationHandler<FixedChildDescriptionImpl>", "DomInvocationHandler");
    doTest("RunConfigurationExtension<Bo>", "RunConfigurationExtension");
    doTest("Comparator<I>", "Comparator");
    doTest("JSResolveUtil.Resolver<M>", "Resolver");
    doTest("JSResolveUtil.F", "F");
    doTest("Model<Inner>", "Model");
    doTest("Comparator<A.B>", "Comparator");
    doTest("IConverter<N>", "IConverter");
    doTest("AbstractNumberConverter<Double>", "AbstractNumberConverter");
    doTest("IConverter<C>", "IConverter");
    doTest("Class<? extends Iterator>", "Class");
    doTest("List<? extends AbstractTreeNode<?>>", "List");
    doTest("Iterator<T>", "Iterator");
    doTest("Class<E>", "Class");
    doTest("Comparator<byte[]>", "Comparator");
    doTest("C<T,T>", "C");
    doTest("A2<T>", "A2");
    doTest("A3<T>", "A3");
    doTest("IB<", "IB");
    doTest("A<S>", "A");
    doTest("B<String>", "B");
    doTest("List<List<T>>", "List");
    doTest("I<A[]>", "I");
    doTest("I<B[]>", "I");
    doTest("A<S,T>", "A");
    doTest("F<A, P1<B>>", "F");
    doTest("Iterable<T>", "Iterable");
    doTest("A<Integer>", "A");
    doTest("Pair<A, B>", "Pair");
    doTest("Field<Object>", "Field");
    doTest("MyInterface<Object>", "MyInterface");
    doTest("Class<I>", "Class");
    doTest("Outer.Inner", "Inner");
    doTest("Comparator<K>", "Comparator");
    doTest("Comparable<SelfComparable>", "Comparable");
    doTest("Collection<T>", "Collection");
    doTest("Collection<E>", "Collection");
    doTest("Iterator<E>", "Iterator");
    doTest("UnmodifiableCollection<E>", "UnmodifiableCollection");
    doTest("Set<E>", "Set");
    doTest("SortedSet<T>", "SortedSet");
    doTest("UnmodifiableSet<E>", "UnmodifiableSet");
    doTest("SortedSet<E>", "SortedSet");
    doTest("ListIterator<E>", "ListIterator");
    doTest("UnmodifiableList<E>", "UnmodifiableList");
    doTest("UnmodifiableSet<Map.Entry<K,V>>", "UnmodifiableSet");
    doTest("Iterator<Map.Entry<K,V>>", "Iterator");
    doTest("Map.Entry<K,V>", "Entry");
    doTest("SortedMap<K,V>", "SortedMap");
    doTest("UnmodifiableMap<K,V>", "UnmodifiableMap");
    doTest("SynchronizedCollection<E>", "SynchronizedCollection");
    doTest("SynchronizedSet<E>", "SynchronizedSet");
    doTest("SynchronizedList<E>", "SynchronizedList");
    doTest("SynchronizedMap<K,V>", "SynchronizedMap");
    doTest("CheckedCollection<E>", "CheckedCollection");
    doTest("CheckedSet<E>", "CheckedSet");
    doTest("CheckedList<E>", "CheckedList");
    doTest("Set<Map.Entry<K,V>>", "Set");
    doTest("CheckedMap<K,V>", "CheckedMap");
    doTest("AbstractSet<Object>", "AbstractSet");
    doTest("Iterator<Object>", "Iterator");
    doTest("AbstractList<Object>", "AbstractList");
    doTest("AbstractMap<Object,Object>", "AbstractMap");
    doTest("AbstractSet<E>", "AbstractSet");
    doTest("AbstractList<E>", "AbstractList");
    doTest("AbstractMap<K,V>", "AbstractMap");
    doTest("Comparator<T>", "Comparator");
    doTest("Comparator<Comparable<Object>>", "Comparator");
    doTest("Enumeration<T>", "Enumeration");
    doTest("java.util.SortedMap", "SortedMap");
    doTest("java.util.AbstractList", "AbstractList");
    doTest("java.util.TreeMap", "TreeMap");
    doTest("java.util.concurrent.atomic.AtomicBoolean", "AtomicBoolean");
    doTest("x.n.X1", "X1");
    doTest("x.n.X2", "X2");
    doTest("x.n.X3", "X3");
    doTest("java.util.X", "X");
    doTest("java.io.Reader", "Reader");
    doTest("java.security.cert.Certificate", "Certificate");
    doTest("i<", "i");
    doTest("ii<", "ii");
    doTest("i2<", "i2");
    doTest("A57.X", "X");
    doTest("A.B", "B");
    doTest("A42.B", "B");
    doTest("B57.X", "X");
    doTest("c4<", "c4");
    doTest("i7<", "i7");
    doTest("c8<", "c8");
    doTest("i5<", "i5");
    doTest("ConflictWithObject<", "ConflictWithObject");
    doTest("MethodsFromObject<", "MethodsFromObject");
    doTest("java.awt.event.ActionEvent", "ActionEvent");
    doTest("a<", "a");
    doTest("A1<", "A1");
    doTest("Foo<", "Foo");
    doTest("c2<", "c2");
    doTest("c1<", "c1");
    doTest("java.awt.BufferCapabilities", "BufferCapabilities");
    doTest("java.io.ObjectOutput", "ObjectOutput");
    doTest("java.io.ObjectInput", "ObjectInput");
    doTest("java.lang.ClassNotFoundException", "ClassNotFoundException");
    doTest("IFoo.UNKNOWN", "UNKNOWN");
    doTest("Integer.MAX_VALUE", "MAX_VALUE");
    doTest("Inner1<", "Inner1");
    doTest("D.B", "B");
    doTest("D.", "");
    doTest("D.B1", "B1");
    doTest("A.B1", "B1");
    doTest("C1.B1", "B1");
    doTest("@java.lang.SuppressWarnings", "SuppressWarnings");
    doTest("BaseStream<T>", "BaseStream");
    doTest("StreamOp<E_IN, Node<E_OUT>>", "StreamOp");
    doTest("IntermediateOp<E_IN, E_OUT>", "IntermediateOp");
    doTest("StreamOp<E_IN, R>", "StreamOp");
    doTest("StatefulOp<T, T>", "StatefulOp");
    doTest("Foo1<Integer, Integer>", "Foo1");
    doTest("List<B>", "List");
    doTest("Optional<U>", "Optional");
    doTest("BiFunction<T, T, T>", "BiFunction");
    doTest("Collector<T, M1>", "Collector");
    doTest("BinaryOperator<M2>", "BinaryOperator");
    doTest("Collector<T, R>", "Collector");
    doTest("C<T, M1>", "C");
    doTest("BiOp<M2>", "BiOp");
    doTest("C<T, R>", "C");
    doTest("BiFun<T, T, T>", "BiFun");
    doTest("Map<A, B>", "Map");
    doTest("Map<K1, M1>", "Map");
    doTest("FindOp<MT, Optional<MT>>", "FindOp");
    doTest("TerminalSink<FindSinkT, FindSinkO>", "TerminalSink");
    doTest("FindSink<OfRefT, Optional<OfRefT>>", "FindSink");
    doTest("FindOp1<MT, Optional<MT>>", "FindOp1");
    doTest("FindOp2<MT, Optional<MT>>", "FindOp2");
    doTest("Optional<T>", "Optional");
    doTest("Consumer<T>", "Consumer");
    doTest("@FunctionalInterface", "FunctionalInterface");
    doTest("Sink<Integer>", "Sink");
    doTest("Sink<T>", "Sink");
    doTest("FirstParent<", "FirstParent");
    doTest("Block<T>", "Block");
    doTest("TerminalSink<T, Void>", "TerminalSink");
    doTest("VoidTerminalSink<Integer>", "VoidTerminalSink");
    doTest("Sink.OfInt", "OfInt");
    doTest("VoidTerminalSink.OfInt<", "OfInt");
    doTest("ForEachOp<T>", "ForEachOp");
    doTest("VoidTerminalSink.OfInt", "OfInt");
    doTest("Iso<R, T>", "Iso");
    doTest("I<X>", "I");
    doTest("I1<T>", "I1");
    doTest("I2<T>", "I2");
    doTest("Y<Object>", "Y");
    doTest("BinaryOperator<Integer>", "BinaryOperator");
    doTest("Combiner<T,T,T>", "Combiner");
    doTest("IntermediateOp<L, M>", "IntermediateOp");
    doTest("IntermediateOp1<T, U>", "IntermediateOp1");
    doTest("I<A,B>", "I");
    doTest("A<L>", "A");
    doTest("SameArgsI<T>", "SameArgsI");
    doTest("LambdaTest<U>", "LambdaTest");
    doTest("Option<T>", "Option");
    doTest("Function<T, Integer>", "Function");
    doTest("BaseStream<Integer>", "BaseStream");
    doTest("Comparator<Map.Entry<K, V>>", "Comparator");
    doTest("Function<T, T>", "Function");
    doTest("A<M>", "A");
    doTest("Foo<X>", "Foo");
    doTest("Iterable<U>", "Iterable");
    doTest("ASink<R, Moo>", "ASink");
    doTest("ASink<AAMoo, AAMoo>", "ASink");
    doTest("ASink<R, AAAMoo>", "ASink");
    doTest("Collector<T, C>", "Collector");
    doTest("Collector<T, List<T>>", "Collector");
    doTest("Stream<C>", "Stream");
    doTest("BiFunction<T,T,T>", "BiFunction");
    doTest("Collector<Integer, R>", "Collector");
    doTest("C.E2", "E2");
    doTest("C.E1", "E1");
    doTest("java.nio.charset.Charset", "Charset");
    doTest("java.nio.charset.CharsetDecoder", "CharsetDecoder");
    doTest("I<String>", "I");
    doTest("InOut<B>", "InOut");
    doTest("DeeBee<B>", "DeeBee");
    doTest("b<C.D>", "b");
    doTest("b<String>", "b");
    doTest("Foo.Bar", "Bar");
    doTest("@Attr", "Attr");
    doTest("javax.swing.table.TableModel", "TableModel");
    doTest("javax.swing.event.TableModelListener", "TableModelListener");
    doTest("@BeanAware", "BeanAware");
    doTest("java.awt.MenuContainer", "MenuContainer");
    doTest("java.lang.Number", "Number");
    doTest("Foo<Bug>", "Foo");
    doTest("Seq<T>", "Seq");
    doTest("Seq<V>", "Seq");
    doTest("Comparable<R>", "Comparable");
    doTest("@org.jetbrains.annotations.NonNls", "NonNls");
    doTest("org.jetbrains.annotations.NonNls", "NonNls");
    doTest("@NonNls", "NonNls");
    doTest("MatchOp<T>", "MatchOp");
    doTest("BooleanTerminalSink<T>", "BooleanTerminalSink");
    doTest("Callable<String>", "Callable");
    doTest("Callable<Integer>", "Callable");
    doTest("AsyncTask<String, Integer, Long>", "AsyncTask");
    doTest("AsyncTask<String,Integer,Integer>", "AsyncTask");
    doTest("List<AppInfo>", "List");
    doTest("ArrayList<ResolveInfo>", "ArrayList");
    doTest("CallableEx<String>", "CallableEx");
    doTest("Callable<TE>", "Callable");
    doTest("CallableEx<Integer>", "CallableEx");
    doTest("TestCase<caret>", "TestCase");
    doTest("@org.ju", "ju");
    doTest("l.InLib", "InLib");
    doTest("junit.framework.Assert", "Assert");
    doTest("junit.framework.TestCase", "TestCase");
    doTest("junit.framework.Test", "Test");
    doTest("junit.framework.TestSuite", "TestSuite");
    doTest("junit.framework.TestResult", "TestResult");
    doTest("junit.framework.TestListener", "TestListener");
    doTest("junit.framework.TestFailure", "TestFailure");
    doTest("junit.framework.ComparisonFailure", "ComparisonFailure");
    doTest("junit.framework.AssertionFailedError", "AssertionFailedError");
    doTest("x.InA", "InA");
    doTest("y.AddDependency", "AddDependency");
    doTest("y.AddLibrary", "AddLibrary");
    doTest("x.DoTest", "DoTest");
    doTest("@org.junit.Test", "Test");
    doTest("org.junit.Test", "Test");
    doTest("x.DoTest4", "DoTest4");
    doTest("Some<K, T>", "Some");
    doTest("java.util.Collection<? super T>", "Collection");
    doTest("I.FOO", "FOO");
    doTest("I.FOO1", "FOO1");
    doTest("I.FOO2", "FOO2");
    doTest("I.FOO3", "FOO3");
    doTest("I.FOO4", "FOO4");
    doTest("I.FOO5", "FOO5");
    doTest("@java.lang.SafeVarargs", "SafeVarargs");
    doTest("M<T>", "M");
    doTest("M<String>", "M");
    doTest("@javax.annotation.Generated", "Generated");
    doTest("II<String>", "II");
    doTest("AroundTemplateMethod<T>", "AroundTemplateMethod");
    doTest("SetupTimer<Integer>", "SetupTimer");
    doTest("bar.Log", "Log");
    doTest("@Bar.Foo", "Foo");
    doTest("I<Object>", "I");
    doTest("Superclass<E, Q>", "Superclass");
    doTest("@org.testng.annotations.Test", "Test");
    doTest("@org.junit.Before", "Before");
    doTest("Ref<T>", "Ref");
    doTest("M<MX, MY>", "M");
    doTest("Proc<String>", "Proc");
    doTest("Proc<Integer>", "Proc");
    doTest("java.util.Iterator", "Iterator");
    doTest("p1.Base", "Base");
    doTest("javax.swing.Icon", "Icon");
    doTest("java.awt.Dialog", "Dialog");
    doTest("javax.swing.JLabel", "JLabel");
    doTest("test.Matcher", "Matcher");
    doTest("java.util.Collections.CopiesList", "CopiesList");
    doTest("java.util.Collections.EmptyList", "EmptyList");
    doTest("java.util.Collections.EmptyMap", "EmptyMap");
    doTest("java.util.Collections.EmptySet", "EmptySet");
    doTest("java.util.Collections.ReverseComparator", "ReverseComparator");
    doTest("java.util.Collections.ReverseComparator2", "ReverseComparator2");
    doTest("java.util.Collections.SelfComparable", "SelfComparable");
    doTest("java.util.Collections.SingletonList", "SingletonList");
    doTest("java.util.Collections.SingletonMap", "SingletonMap");
    doTest("java.util.Collections.SingletonMap.ImmutableEntry", "ImmutableEntry");
    doTest("java.util.Collections.SingletonSet", "SingletonSet");
    doTest("java.util.Collections.SynchronizedCollection", "SynchronizedCollection");
    doTest("java.util.Collections.SynchronizedList", "SynchronizedList");
    doTest("java.util.Collections.SynchronizedMap", "SynchronizedMap");
    doTest("java.util.Collections.SynchronizedRandomAccessList", "SynchronizedRandomAccessList");
    doTest("java.util.Collections.SynchronizedSet", "SynchronizedSet");
    doTest("java.util.Collections.SynchronizedSortedMap", "SynchronizedSortedMap");
    doTest("java.util.Collections.SynchronizedSortedSet", "SynchronizedSortedSet");
    doTest("java.util.Collections.UnmodifiableCollection", "UnmodifiableCollection");
    doTest("java.util.Collections.UnmodifiableList", "UnmodifiableList");
    doTest("java.util.Collections.UnmodifiableMap", "UnmodifiableMap");
    doTest("java.util.Collections.UnmodifiableMap.UnmodifiableEntrySet", "UnmodifiableEntrySet");
    doTest("java.util.Collections.UnmodifiableMap.UnmodifiableEntrySet.UnmodifiableEntry", "UnmodifiableEntry");
    doTest("java.util.Collections.UnmodifiableRandomAccessList", "UnmodifiableRandomAccessList");
    doTest("java.util.Collections.UnmodifiableSet", "UnmodifiableSet");
    doTest("java.util.Collections.UnmodifiableSortedMap", "UnmodifiableSortedMap");
    doTest("java.util.Collections.UnmodifiableSortedSet", "UnmodifiableSortedSet");
    doTest("java.util.Map.Entry", "Entry");
    doTest("AnnotatedNonStaticInnerClassConstructor.Inner", "Inner");
    doTest("pack.Modifiers", "Modifiers");
    doTest("pkg.Deprecated", "Deprecated");
    doTest("pkg.package-info", "package-info");
    doTest("pkg.Nested", "Nested");
    doTest("pkg.Nested.Inner1", "Inner1");
    doTest("pkg.Nested.Inner1.Inner2", "Inner2");
    doTest("pkg.SimpleEnum", "SimpleEnum");
    doTest("pkg.EnumWithFields", "EnumWithFields");
    doTest("pkg.NormalClass", "NormalClass");
    doTest("pkg.NormalClass.Inner", "Inner");
    doTest("pkg.Annotations", "Annotations");
    doTest("pkg.Annotations.IndeterminateAnno", "IndeterminateAnno");
    doTest("pkg.Annotations.A4", "A4");
    doTest("pkg.Annotations.A3", "A3");
    doTest("pkg.Annotations.A2", "A2");
    doTest("pkg.Annotations.A1", "A1");
    doTest("pkg.ParameterNames", "ParameterNames");
    doTest("pkg.EmptyEnum", "EmptyEnum");
    doTest("pkg.$BuckClass", "$BuckClass");
    doTest("pkg.BuckClass$", "BuckClass$");
    doTest("pkg.ExtMethods", "ExtMethods");
    doTest("pkg.MethodReceiver", "MethodReceiver");
    doTest("pkg.MethodReceiver.A", "A");
    doTest("com.google.android.maps.OverlayItem", "OverlayItem");
    doTest("com.google.android.maps.GeoPoint", "GeoPoint");
    doTest("android.graphics.drawable.Drawable", "Drawable");
    doTest("com.TestClass", "TestClass");
    doTest("ppp.BadClass", "BadClass");
    doTest("@AnnotationType", "AnnotationType");
    doTest("@annotations.AnnotationType", "AnnotationType");
    doTest("List<Integer>", "List");
    doTest("List<List<Integer>>", "List");
    doTest("pack.MyClass", "MyClass");
    doTest("p2.A", "A");
    doTest("p1.A", "A");
    doTest("Parent.Child", "Child");
    doTest("net.n3.nanoxml.XMLUtil", "XMLUtil");
    doTest("net.n3.nanoxml.PIReader", "PIReader");
    doTest("net.n3.nanoxml.XMLWriter", "XMLWriter");
    doTest("net.n3.nanoxml.IXMLParser", "IXMLParser");
    doTest("net.n3.nanoxml.XMLElement", "XMLElement");
    doTest("net.n3.nanoxml.CDATAReader", "CDATAReader");
    doTest("net.n3.nanoxml.IXMLElement", "IXMLElement");
    doTest("net.n3.nanoxml.NonValidator", "NonValidator");
    doTest("net.n3.nanoxml.StdXMLParser", "StdXMLParser");
    doTest("net.n3.nanoxml.StdXMLReader", "StdXMLReader");
    doTest("net.n3.nanoxml.XMLAttribute", "XMLAttribute");
    doTest("net.n3.nanoxml.StdXMLReader.StackedReader", "StackedReader");
    doTest("net.n3.nanoxml.XMLException", "XMLException");
    doTest("net.n3.nanoxml.ContentReader", "ContentReader");
    doTest("net.n3.nanoxml.StdXMLBuilder", "StdXMLBuilder");
    doTest("net.n3.nanoxml.ValidatorPlugin", "ValidatorPlugin");
    doTest("net.n3.nanoxml.XMLParserFactory", "XMLParserFactory");
    doTest("net.n3.nanoxml.XMLEntityResolver", "XMLEntityResolver");
    doTest("net.n3.nanoxml.XMLParseException", "XMLParseException");
    doTest("net.n3.nanoxml.XMLValidationException", "XMLValidationException");
    doTest("com.google.protobuf.Message", "Message");
    doTest("com.google.protobuf.RpcUtil", "RpcUtil");
    doTest("com.google.protobuf.Service", "Service");
    doTest("com.google.protobuf.Message.Builder", "Builder");
    doTest("com.google.protobuf.FieldSet", "FieldSet");
    doTest("com.google.protobuf.FieldSet.FieldDescriptorLite", "FieldDescriptorLite");
    doTest("com.google.protobuf.Internal", "Internal");
    doTest("com.google.protobuf.RpcUtil.AlreadyCalledException", "AlreadyCalledException");
    doTest("com.google.protobuf.Internal.EnumLiteMap", "EnumLiteMap");
    doTest("com.google.protobuf.RpcCallback<Type>", "RpcCallback");
    doTest("com.google.protobuf.Internal.EnumLite", "EnumLite");
    doTest("com.google.protobuf.MessageLite", "MessageLite");
    doTest("com.google.protobuf.MessageOrBuilder", "MessageOrBuilder");
    doTest("com.google.protobuf.MessageLite.Builder", "Builder");
    doTest("com.google.protobuf.RpcCallback<com.google.protobuf.Message>", "RpcCallback");
    doTest("com.google.protobuf.ByteString", "ByteString");
    doTest("com.google.protobuf.RpcCallback<ParameterType>", "RpcCallback");
    doTest("com.google.protobuf.RpcChannel", "RpcChannel");
    doTest("com.google.protobuf.ByteString.CodedBuilder", "CodedBuilder");
    doTest("com.google.protobuf.TextFormat", "TextFormat");
    doTest("com.google.protobuf.WireFormat", "WireFormat");
    doTest("com.google.protobuf.TextFormat.InvalidEscapeSequenceException", "InvalidEscapeSequenceException");
    doTest("com.google.protobuf.WireFormat.FieldType", "FieldType");
    doTest("com.google.protobuf.ByteString.Output", "Output");
    doTest("com.google.protobuf.TextFormat.ParseException", "ParseException");
    doTest("com.google.protobuf.TextFormat.Tokenizer", "Tokenizer");
    doTest("com.google.protobuf.WireFormat.JavaType", "JavaType");
    doTest("java.io.FilterOutputStream", "FilterOutputStream");
    doTest("java.lang.Comparable<T>", "Comparable");
    doTest("com.google.protobuf.FieldSet<T>", "FieldSet");
    doTest("com.google.protobuf.Descriptors", "Descriptors");
    doTest("com.google.protobuf.RpcCallback", "RpcCallback");
    doTest("com.google.protobuf.Descriptors.DescriptorPool", "DescriptorPool");
    doTest("com.google.protobuf.RpcController", "RpcController");
    doTest("com.google.protobuf.DynamicMessage", "DynamicMessage");
    doTest("com.google.protobuf.Descriptors.DescriptorPool.DescriptorIntPair", "DescriptorIntPair");
    doTest("com.google.protobuf.DynamicMessage.Builder", "Builder");
    doTest("com.google.protobuf.TextFormat.TextGenerator", "TextGenerator");
    doTest("com.google.protobuf.Descriptors.DescriptorPool.PackageDescriptor", "PackageDescriptor");
    doTest("com.google.protobuf.MessageLiteOrBuilder", "MessageLiteOrBuilder");
    doTest("com.google.protobuf.TextFormat.Printer", "Printer");
    doTest("com.google.protobuf.LazyStringList", "LazyStringList");
    doTest("java.util.List<java.lang.String>", "List");
    doTest("com.google.protobuf.SmallSortedMap", "SmallSortedMap");
    doTest("com.google.protobuf.SmallSortedMap.EmptySet", "EmptySet");
    doTest("com.google.protobuf.SmallSortedMap.EntryIterator", "EntryIterator");
    doTest("com.google.protobuf.SmallSortedMap.EntrySet", "EntrySet");
    doTest("com.google.protobuf.SmallSortedMap.Entry", "Entry");
    doTest("java.util.AbstractMap<K,V>", "AbstractMap");
    doTest("java.lang.Iterable<T>", "Iterable");
    doTest("java.util.Iterator<java.util.Map.Entry<K,V>>", "Iterator");
    doTest("java.util.AbstractSet<java.util.Map.Entry<K,V>>", "AbstractSet");
    doTest("java.lang.Comparable<com.google.protobuf.SmallSortedMap<K,V>.Entry>", "Comparable");
    doTest("com.google.protobuf.SmallSortedMap<FieldDescriptorType,java.lang.Object>", "SmallSortedMap");
    doTest("com.google.protobuf.SmallSortedMap<K,V>", "SmallSortedMap");
    doTest("com.google.protobuf.AbstractMessage", "AbstractMessage");
    doTest("com.google.protobuf.AbstractMessage.Builder<com.google.protobuf.DynamicMessage.Builder>", "Builder");
    doTest("com.google.protobuf.Descriptors.DescriptorValidationException", "DescriptorValidationException");
    doTest("com.google.protobuf.BlockingService", "BlockingService");
    doTest("com.google.protobuf.AbstractMessage.Builder", "Builder");
    doTest("com.google.protobuf.Descriptors.GenericDescriptor", "GenericDescriptor");
    doTest("com.google.protobuf.UnknownFieldSet", "UnknownFieldSet");
    doTest("com.google.protobuf.UnknownFieldSet.Field", "Field");
    doTest("com.google.protobuf.Descriptors.MethodDescriptor", "MethodDescriptor");
    doTest("com.google.protobuf.UnknownFieldSet.Field.Builder", "Builder");
    doTest("com.google.protobuf.CodedInputStream", "CodedInputStream");
    doTest("com.google.protobuf.UnknownFieldSet.Builder", "Builder");
    doTest("com.google.protobuf.Descriptors.ServiceDescriptor", "ServiceDescriptor");
    doTest("com.google.protobuf.AbstractMessageLite", "AbstractMessageLite");
    doTest("com.google.protobuf.AbstractMessageLite.Builder<BuilderType>", "Builder");
    doTest("com.google.protobuf.UninitializedMessageException", "UninitializedMessageException");
    doTest("com.google.protobuf.GeneratedMessage", "GeneratedMessage");
    doTest("com.google.protobuf.GeneratedMessage.FieldAccessorTable", "FieldAccessorTable");
    doTest("com.google.protobuf.GeneratedMessage.FieldAccessorTable.RepeatedMessageFieldAccessor", "RepeatedMessageFieldAccessor");
    doTest("com.google.protobuf.Descriptors.EnumValueDescriptor", "EnumValueDescriptor");
    doTest("com.google.protobuf.ServiceException", "ServiceException");
    doTest("com.google.protobuf.Descriptors.EnumDescriptor", "EnumDescriptor");
    doTest("com.google.protobuf.GeneratedMessage.FieldAccessorTable.SingularMessageFieldAccessor", "SingularMessageFieldAccessor");
    doTest("com.google.protobuf.CodedOutputStream", "CodedOutputStream");
    doTest("com.google.protobuf.CodedOutputStream.OutOfSpaceException", "OutOfSpaceException");
    doTest("com.google.protobuf.Descriptors.FieldDescriptor", "FieldDescriptor");
    doTest("com.google.protobuf.GeneratedMessage.FieldAccessorTable.RepeatedEnumFieldAccessor", "RepeatedEnumFieldAccessor");
    doTest("com.google.protobuf.Descriptors.FieldDescriptor.JavaType", "JavaType");
    doTest("com.google.protobuf.ExtensionRegistry", "ExtensionRegistry");
    doTest("com.google.protobuf.ExtensionRegistry.DescriptorIntPair", "DescriptorIntPair");
    doTest("com.google.protobuf.ExtensionRegistry.ExtensionInfo", "ExtensionInfo");
    doTest("com.google.protobuf.Descriptors.FieldDescriptor.Type", "Type");
    doTest("com.google.protobuf.GeneratedMessage.FieldAccessorTable.SingularEnumFieldAccessor", "SingularEnumFieldAccessor");
    doTest("com.google.protobuf.ExtensionRegistryLite", "ExtensionRegistryLite");
    doTest("com.google.protobuf.BlockingRpcChannel", "BlockingRpcChannel");
    doTest("com.google.protobuf.SingleFieldBuilder", "SingleFieldBuilder");
    doTest("com.google.protobuf.GeneratedMessage.BuilderParent", "BuilderParent");
    doTest("com.google.protobuf.GeneratedMessage.FieldAccessorTable.RepeatedFieldAccessor", "RepeatedFieldAccessor");
    doTest("com.google.protobuf.AbstractMessageLite.Builder", "Builder");
    doTest("com.google.protobuf.AbstractMessageLite.Builder.LimitedInputStream", "LimitedInputStream");
    doTest("java.io.FilterInputStream", "FilterInputStream");
    doTest("com.google.protobuf.LazyStringArrayList", "LazyStringArrayList");
    doTest("com.google.protobuf.GeneratedMessage.FieldAccessorTable.SingularFieldAccessor", "SingularFieldAccessor");
    doTest("java.util.AbstractList<java.lang.String>", "AbstractList");
    doTest("java.util.RandomAccess", "RandomAccess");
    doTest("com.google.protobuf.ProtocolMessageEnum", "ProtocolMessageEnum");
    doTest("com.google.protobuf.GeneratedMessageLite", "GeneratedMessageLite");
    doTest("com.google.protobuf.GeneratedMessageLite.SerializedForm", "SerializedForm");
    doTest("com.google.protobuf.GeneratedMessageLite.GeneratedExtension", "GeneratedExtension");
    doTest("com.google.protobuf.GeneratedMessage.FieldAccessorTable.FieldAccessor", "FieldAccessor");
    doTest("com.google.protobuf.Descriptors.Descriptor", "Descriptor");
    doTest("com.google.protobuf.GeneratedMessageLite.ExtensionDescriptor", "ExtensionDescriptor");
    doTest("com.google.protobuf.GeneratedMessage.GeneratedExtension", "GeneratedExtension");
    doTest("com.google.protobuf.GeneratedMessageLite.Builder", "Builder");
    doTest("com.google.protobuf.GeneratedMessage.ExtensionDescriptorRetriever", "ExtensionDescriptorRetriever");
    doTest("com.google.protobuf.FieldSet.FieldDescriptorLite<com.google.protobuf.GeneratedMessageLite.ExtensionDescriptor>", "FieldDescriptorLite");
    doTest("com.google.protobuf.GeneratedMessageLite.Builder<MessageType,BuilderType>", "Builder");
    doTest("com.google.protobuf.GeneratedMessageLite.GeneratedExtension<ContainingType,Type>", "GeneratedExtension");
    doTest("com.google.protobuf.Descriptors.FileDescriptor", "FileDescriptor");
    doTest("com.google.protobuf.RepeatedFieldBuilder", "RepeatedFieldBuilder");
    doTest("com.google.protobuf.Descriptors.FileDescriptor.InternalDescriptorAssigner", "InternalDescriptorAssigner");
    doTest("com.google.protobuf.RepeatedFieldBuilder.MessageOrBuilderExternalList", "MessageOrBuilderExternalList");
    doTest("com.google.protobuf.RepeatedFieldBuilder.BuilderExternalList", "BuilderExternalList");
    doTest("com.google.protobuf.RepeatedFieldBuilder.MessageExternalList", "MessageExternalList");
    doTest("java.util.AbstractList<IType>", "AbstractList");
    doTest("java.util.List<IType>", "List");
    doTest("java.util.AbstractList<BType>", "AbstractList");
    doTest("java.util.List<BType>", "List");
    doTest("java.util.AbstractList<MType>", "AbstractList");
    doTest("java.util.List<MType>", "List");
    doTest("com.google.protobuf.ExtensionRegistryLite.ObjectIntPair", "ObjectIntPair");
    doTest("com.google.protobuf.GeneratedMessage.Builder", "Builder");
    doTest("com.google.protobuf.Internal.EnumLiteMap<com.google.protobuf.Descriptors.EnumValueDescriptor>", "EnumLiteMap");
    doTest("java.lang.Comparable<com.google.protobuf.Descriptors.FieldDescriptor>", "Comparable");
    doTest("com.google.protobuf.FieldSet.FieldDescriptorLite<com.google.protobuf.Descriptors.FieldDescriptor>", "FieldDescriptorLite");
    doTest("com.google.protobuf.GeneratedMessage.Builder.BuilderParentImpl", "BuilderParentImpl");
    doTest("com.google.protobuf.UnmodifiableLazyStringList", "UnmodifiableLazyStringList");
    doTest("Map<Integer, Integer>", "Map");
    doTest("java.lang.Comparable<T.NameRef>", "Comparable");
    doTest("List<T[]>", "List");
    doTest("Condition<T>", "Condition");
    doTest("Class<Foo>", "Class");
    doTest("Class<Runnable>", "Class");
    doTest("Foo<BarImpl>", "Foo");
    doTest("Y<T>", "Y");
    doTest("GenericClass<String>", "GenericClass");
    doTest("A.I", "I");
    doTest("Test<T>", "Test");
    doTest("Comparable<Integer>", "Comparable");
    doTest("Iterator<Map.Entry<K, V>>", "Iterator");
    doTest("Predicate<T>", "Predicate");
    doTest("Foo.Predicate<T>", "Predicate");
    doTest("Callable<Object>", "Callable");
    doTest("C<String>", "C");
    doTest("p1.S2", "S2");
    doTest("p2.S1", "S1");
    doTest("p1.S1", "S1");
    doTest("p2.S2", "S2");
    doTest("p2.p1.S1", "S1");
    doTest("p2.p1.S2", "S2");
    doTest("@javax.xml.bind.annotation.XmlSchema", "XmlSchema");
    doTest("A <R>", "A");
    doTest("Extracted.Inner", "Inner");
    doTest("java.util.List<String>", "List");
    doTest("@java.lang.Override", "Override");
    doTest("a.Test", "Test");
    doTest("b.TestSubclass", "TestSubclass");
    doTest("java.util.ListIterator", "ListIterator");
    doTest("p1.AA", "AA");
    doTest("p2.C", "C");
    doTest("java.math.BigDecimal", "BigDecimal");
    doTest("java.sql.SQLWarning", "SQLWarning");
    doTest("java.sql.ResultSetMetaData", "ResultSetMetaData");
    doTest("java.sql.Statement", "Statement");
    doTest("java.sql.Ref", "Ref");
    doTest("java.sql.Blob", "Blob");
    doTest("java.sql.Clob", "Clob");
    doTest("java.sql.Array", "Array");
    doTest("java.sql.ResultSet", "ResultSet");
    doTest("p.Test", "Test");
    doTest("p1.Usage", "Usage");
    doTest("Super<R>", "Super");
    doTest("java.lang.Comparable<java.lang.Long>", "Comparable");
    doTest("R<String, Object>", "R");
    doTest("Res.R<java.lang.String,java.lang.Object>", "R");
    doTest("Res.R<String,java.lang.Object>", "R");
    doTest("Res.R<String,Object>", "R");
    doTest("Res.R<String, Object>", "R");
    doTest("@Before", "Before");
    doTest("org.junit.Before", "Before");
    doTest("Test<G, T>", "Test");
    doTest("p.Param", "Param");
    doTest("p2.Test", "Test");
    doTest("pack1.Class2", "Class2");
    doTest("pack2.Class1", "Class1");
    doTest("pack1.X", "X");
    doTest("pack2.X", "X");
    doTest("pack2.A", "A");
    doTest("pack1.Class1", "Class1");
    doTest("packUser.Class2", "Class2");
    doTest("pack0.Class0", "Class0");
    doTest("pack2.A.Class1", "Class1");
    doTest("A.Class1", "Class1");
    doTest("pack1.Usage", "Usage");
    doTest("pack1.StaticInner", "StaticInner");
    doTest("pack1.Client", "Client");
    doTest("xxx.Outer", "Outer");
    doTest("p.A.B", "B");
    doTest("p.A", "A");
    doTest("p.B", "B");
    doTest("package2.InnerClass", "InnerClass");
    doTest("package1.OuterClass", "OuterClass");
    doTest("pack1.DImpl", "DImpl");
    doTest("pack1.A", "A");
    doTest("pack1.B", "B");
    doTest("pack2.B", "B");
    doTest("pack1.Outer", "Outer");
    doTest("POne<Hooray<A>>", "POne");
    doTest("Eff<POne<A>, A>", "Eff");
    doTest("@SomeAnnotation", "SomeAnnotation");
    doTest("pack2.OtherClass", "OtherClass");
    doTest("pack1.ClassWithStaticMethod", "ClassWithStaticMethod");
    doTest("bar.A", "A");
    doTest("A.Inner", "Inner");
    doTest("B.Inner", "Inner");
    doTest("target.pack1.S1", "S1");
    doTest("pack2.UsagesFromBoth", "UsagesFromBoth");
    doTest("pack2.UsagesFromBoth2", "UsagesFromBoth2");
    doTest("Parent<T>", "Parent");
    doTest("Parent<String>", "Parent");
    doTest("I<S>", "I");
    doTest("Base<U>", "Base");
    doTest("javax.swing.JTextField", "JTextField");
    doTest("Test<Throwable>", "Test");
    doTest("BaseTask<T, ForEachTask<T>>", "BaseTask");
    doTest("pack1.List", "List");
    doTest("pack2.Usage2", "Usage2");
    doTest("pack2.Usage", "Usage");
    doTest("pack1.ParentXXX", "ParentXXX");
    doTest("pack1.Derived", "Derived");
    doTest("pack1.Object", "Object");
    doTest("renameCollisions.String", "String");
    doTest("javax.swing.SwingConstants", "SwingConstants");
    doTest("Holder<X>", "Holder");
    doTest("MyEventListener<Object>", "MyEventListener");
    doTest("foo.Builder", "Builder");
    doTest("Test<A, B, C>", "Test");
    doTest("B<TC>", "B");
    doTest("A<TB>", "A");
    doTest("A<TC>", "A");
    doTest("pack1.AnInterface", "AnInterface");
    doTest("pack1.AClass", "AClass");
    doTest("pack2.Client", "Client");
    doTest("Int<Xyz>", "Int");
    doTest("Int<XInt>", "Int");
    doTest("Factory<IntF>", "Factory");
    doTest("Factory<Clazz>", "Factory");
    doTest("LinkedList<Integer>", "LinkedList");
    doTest("LinkedList<E, T>", "LinkedList");
    doTest("LinkedList<E, Integer>", "LinkedList");
    doTest("Map<Integer, Y>", "Map");
    doTest("List<X>", "List");
    doTest("Collection<X>", "Collection");
    doTest("List<P>", "List");
    doTest("C<String,Integer>", "C");
    doTest("C<Integer, String,Integer>", "C");
    doTest("C<Integer, String >", "C");
    doTest("C<String, L<String>>", "C");
    doTest("Subject<String>", "Subject");
    doTest("Subject<SubjectFace, Set<Object>>", "Subject");
    doTest("Subject<SubjectFace, java.util.Set<Object>>", "Subject");
    doTest("X<U>", "X");
    doTest("java.util.TreeMap.Entry", "Entry");
    doTest("java.util.TreeMap.Entry<K,?>", "Entry");
    doTest("java.util.TreeMap.Entry<K,V>", "Entry");
    doTest("java.util.Comparator<? super K>", "Comparator");
    doTest("WeighingComparable<T, Loc>", "WeighingComparable");
    doTest("Key<ProximityWeigher>", "Key");
    doTest("Weigher<String, ProximityLocation>", "Weigher");
    doTest("Comparable<WeighingComparable<T, Loc>>", "Comparable");
    doTest("p1.ParentWithProtected", "ParentWithProtected");
    doTest("p1.SubjectWithSuper", "SubjectWithSuper");
    doTest("p2.Usage", "Usage");
    doTest("p1.ParentUniqueName", "ParentUniqueName");
    doTest("p1.ChildCtor", "ChildCtor");
    doTest("java.util.Comparator<String>", "Comparator");
    doTest("Demo.MyParent", "MyParent");
    doTest("A.MyActionListener", "MyActionListener");
    doTest("Comparable<T>", "Comparable");
    doTest("qqq.aaa.Yahoo", "Yahoo");
    doTest("p1.C1", "C1");
    doTest("zzz.bbb.QQQ", "QQQ");
  }

  @Test
  public void shortNameWithTypeAnnotations() {
    doTest("java.util.@NotAllowed Date", "Date");
    doTest("@IllegalSyntax java.util.Date", "Date");
    doTest("Map<@NonNull String, @NonEmpty List<@Readonly Document>>", "Map");
    doTest("@NonEmpty @Readonly List<@Readonly String>", "List");
    doTest("Map.@NonNull Entry", "Entry");
    doTest("MyClass<@Immutable ? extends Comparable<MyClass>>", "MyClass");
  }

  private static void doTest(String referenceText, String shortName) {
    Assert.assertEquals(shortName, PsiNameHelper.getShortClassName(referenceText));
  }
}
